extends CharacterBody3D


# скрипт-предок для всех движущихся объектов

var uuid = ""
var objekto
var distance = 0 # дистанция до корабля игрока
var integreco = 100 # % целостности объекта
var potenco # мощность ресурса

var acceleration = 1 # для расчета движения корабля
var target_rot #положение корабля, которое надо принять, чтобы нацелиться на точку.
var speed_rotation =1

# максимальная скорость корабля
var max_speed =1000.0


# uuid проекта маршрута
var projekto_itineroj
#маршрут движения корабля
var itineroj = [] 
# uuid - uuid задачи
# front - transform координат цели движения (лучше высчитать один раз при добавлении)
# координаты цели полёта
#			'koordinatoX':
#			'koordinatoY':
#			'koordinatoZ':
# pozicio - в какой позиции должна находится задача
var pause = false # объект стоит на паузе и не летит


func _physics_process(delta):
	if !(itineroj.is_empty() or pause): #Если цель существует, двигаемся
		var front = Transform3D(Basis.IDENTITY,Vector3(itineroj.front()['koordinatoX'],
			itineroj.front()['koordinatoY'], itineroj.front()['koordinatoZ']))
		var target_dir = (front.origin - position).normalized()
		var distance = position.distance_to(front.origin)
		var current_speed = 0
		if len (itineroj)>1:
			if distance <1: #Если это не последняя точка, то мы не тормозим, так что завышаем расстояние, чтобы не проскочить эту точку
				dec_route()
				return
			current_speed = lerp(current_speed,max_speed,delta*acceleration)#ускоряемся
			transform.basis = transform.basis.slerp(target_rot,speed_rotation*delta) #потихоньку поворачиваем корабль на цель. Взято у Сканера из урока про зомбей. Quaternion(transform.basis) - текущий поворот корабля
		else:
			if distance > max_speed*delta/acceleration:#Тут сомнительная формула от фонаря, вычисляющая примерно откуда надо начинать тормозить корабль.
				current_speed = lerp(current_speed,max_speed,delta*acceleration)#ускоряемся
				transform.basis = transform.basis.slerp(target_rot,speed_rotation*delta) #потихоньку поворачиваем корабль на цель. Взято у Сканера из урока про зомбей. Quaternion(transform.basis) - текущий поворот корабля
			else: #Если это  последняя точка, то мы тормозим, и задаём минимальное расстояние, чтобы точнее выставить корабль
				current_speed = lerp(current_speed,50,delta*acceleration)#замедляемся
				if front.basis !=Basis.IDENTITY:
					transform.basis = transform.basis.slerp(Quaternion(front.basis),speed_rotation*delta*1.5) #поворачиваем в дефолтное состояние, чтобы сесть
				if distance <0.01:
					if front.basis !=Basis.IDENTITY:
						transform.basis = front.basis
					position = front.origin
					route_gone()
					return
#		print(distance,": ",current_speed)
#		print(len(itineroj))
#		print('двигаемся = ',target_dir*delta*current_speed)
# warning-ignore:return_value_discarded
		set_velocity(target_dir*delta*current_speed)
		move_and_slide() #Двигаемся к цели  и тут можно передать transform на сервер


func rotate_start():# поворачиваем корабль носом по ходу движения
	var front = Transform3D(Basis.IDENTITY, Vector3(itineroj.front()['koordinatoX'],
		itineroj.front()['koordinatoY'], itineroj.front()['koordinatoZ']))
	target_rot = Quaternion(transform.looking_at(front.origin,Vector3.UP).basis) #запоминаем в какое положение надо установить корабль, чтобы нос был к цели. Это в кватернионах. ХЗ что это, но именно так вращать правильнее всего.


func set_route(route_array):
	if !route_array.is_empty():
		itineroj.clear() #Просто приравнивать нельзя, так как изменяется адрес и если где-то на него кто-то ссылался в других сценах, то он теряет этот адрес Так что очищаем и копируем.
		for i in route_array:
			itineroj.push_back(i)
		rotate_start()


func dec_route():
	itineroj.pop_front()
	set_route(itineroj.duplicate())


func route_gone():
	itineroj.clear()

func add_route(route_array):
	for i in route_array:
		itineroj.push_back(i)
	set_route(itineroj.duplicate())


# редактировать маршрут
func sxangxi_itinero(projekto, tasko):
	if projekto['uuid']==projekto_itineroj: # изменение по задаче в текущем проекте
		var new_tasko = true # признак необходимости новой задачи
		var pos = 0 # номер позиции в списке задач
		for it in itineroj:# проходим по всем задачам
			if tasko['uuid'] == it['uuid']: # нашли соответствующую задачу
				new_tasko = false
				if tasko['statuso']['objId']==1: # новая -  в очередь выполнения 
					it['koordinatoX'] = tasko['finKoordinatoX']
					it['koordinatoY'] = tasko['finKoordinatoY']
					it['koordinatoZ'] = tasko['finKoordinatoZ']
				elif tasko['statuso']['objId']==2: # в работе
					# задача должна быть первой в списке
					if pos: # если не первая
						itineroj.remove(pos)
						itineroj.push_front({
							'uuid':tasko['uuid'],
							'koordinatoX':tasko['finKoordinatoX'],
							'koordinatoY':tasko['finKoordinatoY'],
							'koordinatoZ':tasko['finKoordinatoZ']
						})
					else:
						it['koordinatoX'] = tasko['finKoordinatoX']
						it['koordinatoY'] = tasko['finKoordinatoY']
						it['koordinatoZ'] = tasko['finKoordinatoZ']
					# отправляем корабль на уточнённые координаты, а точнее поворачиваем
					rotate_start()
					pause = false
				elif tasko['statuso']['objId']==4: # закрыта
					#удаляем из списка
					itineroj.remove(pos)
				elif tasko['statuso']['objId']==6: # приостановлена
					pause = true
				break
			pos += 1
		if new_tasko: # добавляем новую задачу в проект
			if tasko['statuso']['objId']==1: # новая -  в очередь выполнения 
				# нужно выстроить по очерёдности
				pass
				pos = 0
				var pozicio = false
				for it in itineroj:# проходим по всем задачам и находим нужную позицию
					if itineroj['pozicio']>tasko['pozicio']: # вставляем перед данной записью
						itineroj.insert(pos, {
							'uuid':tasko['uuid'],
							'koordinatoX': tasko['finKoordinatoX'],
							'koordinatoY': tasko['finKoordinatoY'],
							'koordinatoZ': tasko['finKoordinatoZ'],
							'pozicio': tasko['pozicio']
						})
						pozicio = true
						break
					pos += 1
				if !pozicio: # позиция не найдены, добавляем в конце
					itineroj.push_pop({
						'uuid':tasko['uuid'],
						'koordinatoX': tasko['finKoordinatoX'],
						'koordinatoY': tasko['finKoordinatoY'],
						'koordinatoZ': tasko['finKoordinatoZ'],
						'pozicio': tasko['pozicio']
					})
			elif tasko['statuso']['objId']==2: # в работе
					# задача должна быть первой в списке
				itineroj.push_front({
					'uuid':tasko['uuid'],
					'koordinatoX':tasko['finKoordinatoX'],
					'koordinatoY':tasko['finKoordinatoY'],
					'koordinatoZ':tasko['finKoordinatoZ'],
					'pozicio': tasko['pozicio']
				})
					# отправляем корабль на уточнённые координаты, а точнее поворачиваем
				rotate_start()
				pause = false
			elif tasko['statuso']['objId']==6: # приостановлена
				itineroj.push_front({
					'uuid':tasko['uuid'],
					'koordinatoX': tasko['finKoordinatoX'],
					'koordinatoY': tasko['finKoordinatoY'],
					'koordinatoZ': tasko['finKoordinatoZ'],
					'pozicio': tasko['pozicio']
				})
				pause = true
	else: # первая запись нового проекта
		route_gone()
		projekto_itineroj = projekto['uuid']
		itineroj.push_back({
			'uuid':tasko['uuid'],
			'koordinatoX': tasko['finKoordinatoX'],
			'koordinatoY': tasko['finKoordinatoY'],
			'koordinatoZ': tasko['finKoordinatoZ'],
			'pozicio': tasko['pozicio']
		})
		if tasko['statuso']['objId']==2: # в работе
			rotate_start()
			pause = false
		else:
			pause = true

